﻿using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Effects;
using Microsoft.Graphics.Canvas.Text;
using Microsoft.Graphics.Canvas.UI;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using 纸片人.AttributeUsageFloder;

// https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“空白页”项模板

namespace 纸片人.PageViews
{
    [PageType("cpu", "火焰效果")]
    /// <summary>
    /// 可用于自身或导航至 Frame 内部的空白页。
    /// </summary>
    public sealed partial class BurningTextExample : Page
    {
        //文本
        string text, newText;
        //字体大小
        float fontSize;


        public BurningTextExample()
        {
            this.InitializeComponent();

            Init();
        }

        private void Init()
        {
            this.Unloaded += (s, e) =>
            {
                canvas.RemoveFocusEngagement();
                canvas = null;
            };
            //文本块文字更改
            textInput.TextChanged += (s, e) => { newText = textInput.Text; };

            canvas.CreateResources += (s, args) =>
            {
                if (args.Reason == CanvasCreateResourcesReason.DpiChanged)
                {
                    //   这些资源都是 DPI 独立的, 因此无需重新创建它们
                    //如果只有 DPI 已更改。
                    return;
                }

                //创建火焰动画
                //CreateFlameEffect();

                text = null;
                newText = textInput.Text;
            };

            canvas.Draw += (sender, args) =>
            {
                //如果文本或字体大小已更改, 则重新创建文本命令列表。
                var newFontSize = GetFontSize(sender.Size);
                if (newText != text || newFontSize != fontSize)
                {
                    text = newText;
                    fontSize = newFontSize;
                }

                float w = newFontSize * text.Length+10;
                float h = newFontSize + 10;
                float x = (float)(sender.Size.Width - w) / 2;
                float y = (float)(sender.Size.Height - h) / 2;
              
                using (var ds = args.DrawingSession)
                {
                    var tcl = new CanvasCommandList(sender);
                    using (var cds = tcl.CreateDrawingSession())
                    {
                        cds.Clear(Colors.Transparent);
                        cds.DrawText(text, 0, 0, Colors.Red, new CanvasTextFormat { FontFamily = "Segoe UI", FontSize = fontSize, HorizontalAlignment = CanvasHorizontalAlignment.Center, VerticalAlignment = CanvasVerticalAlignment.Top });
                    }

                    MorphologyEffect me = new MorphologyEffect
                    {
                        // 源属性由 SetupText () 设置。
                        Mode = MorphologyEffectMode.Dilate,
                        Width = 7,
                        Height = 1
                    };

                    //将命令列表挂钩到火焰效果图中
                    me.Source = tcl;

                    var gaus = new GaussianBlurEffect()
                    {
                        Source = me,
                        BlurAmount = 3f
                    };

                    //模糊, 然后着色文本从黑色到红色, 橙色, 因为 alpha 增加。
                    var color = new ColorMatrixEffect
                    {
                        Source = gaus,
                        ColorMatrix = new Matrix5x4
                        {
                            M11 = 0f,
                            M12 = 0f,
                            M13 = 0f,
                            M14 = 0f,
                            M21 = 0f,
                            M22 = 0f,
                            M23 = 0f,
                            M24 = 0f,
                            M31 = 0f,
                            M32 = 0f,
                            M33 = 0f,
                            M34 = 0f,
                            M41 = 0f,
                            M42 = 1f,
                            M43 = 0f,
                            M44 = 1f,
                            M51 = 1f,
                            M52 = -0.5f,
                            M53 = 0f,
                            M54 = 0f
                        }
                    };
                    //生成柏林噪声字段 (请参见 flamePosition)。
                    var te = new TurbulenceEffect()
                    {
                        Frequency = new Vector2((float)args.Timing.TotalTime.TotalSeconds*0.01f, 0.109f),
                        Size = new Vector2(500f, 80f),
                    };


                    var bor = new BorderEffect()
                    {
                        ExtendX = CanvasEdgeBehavior.Mirror,
                        ExtendY = CanvasEdgeBehavior.Mirror,
                        Source = te,
                    };

                    var animation = new Transform2DEffect
                    {
                        Source = bor,
                        TransformMatrix = Matrix3x2.CreateTranslation(new Vector2(0f))
                    };
                    var disp = new DisplacementMapEffect()
                    {
                        Amount = 20.0f,
                        Source = gaus,
                        Displacement = animation,

                    };
                    //伸展并将火焰放在原文本的后面。
                    var position = new Transform2DEffect
                    {
                        Source = disp
                    };
                   

                    ds.DrawImage(disp, new Vector2(x,y));
                    ds.DrawText(text, x, y, Colors.Gray, new CanvasTextFormat { FontFamily = "Segoe UI", FontSize = fontSize, HorizontalAlignment = CanvasHorizontalAlignment.Center, VerticalAlignment = CanvasVerticalAlignment.Top });
                }
            };
        }


        /// <summary>
        /// 计算良好的字体大小, 以便即使在较小的电话屏幕上文本也适合。
        /// </summary>
        private static float GetFontSize(Size displaySize)
        {
            const float maxFontSize = 72;
            const float scaleFactor = 12;

            return Math.Min((float)displaySize.Width / scaleFactor, maxFontSize);
        }

    }
}
